package boardgamer.yavalath.common;

import boardgamer.common.net.PlayerId;
import com.google.common.base.Objects;

import javax.annotation.Nullable;
import java.io.Serializable;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;


public class YavalathTile implements Serializable {

  private static final long serialVersionUID = -1948155554318723869L;

  @Nullable protected PlayerId owner;
  private final int x;
  private final int y;

  /**
   * Creates a tile without any owners
   */
  public YavalathTile(int x, int y) {
    this.x = x;
    this.y = y;
    this.owner = null;
  }

  public YavalathTile(PlayerId owner, int x, int y) {
    this(x, y);
    this.owner = checkNotNull(owner, "owner");
  }

  public static YavalathTile copyOf(YavalathTile tile) {
    if (tile.hasOwner()) {
      return new YavalathTile(tile.owner, tile.x, tile.y);
    } else {
      return new YavalathTile(tile.x, tile.y);
    }
  }

  public PlayerId getOwner() {
    checkState(hasOwner(), "No owner found");
    return owner;
  }

  public boolean hasOwner() {
    return owner != null;
  }

  public void setOwner(PlayerId playerId) {
    this.owner = checkNotNull(playerId, "playerId");
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof YavalathTile)) {
      return false;
    }

    YavalathTile that = (YavalathTile) obj;
    return Objects.equal(this.owner, that.owner)
        && Objects.equal(this.x, that.x)
        && Objects.equal(this.y, that.y);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(owner, x, y);
  }

  @Override
  public String toString() {
    return Objects.toStringHelper(this)
        .add("owner", owner)
        .add("x", x)
        .add("y", y)
        .toString();
  }
}
